//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

import React, { useEffect, useRef } from "react";
import { observer } from "mobx-react";
import { Layout } from "antd";
import { type CommitGraphInfo, list_commit_graph } from "@/api/local_repo";
import { useGitStores } from "../store";
import { CommitOptions, createGitgraph, MergeStyle } from "@gitgraph/js";
import { appWindow, WebviewWindow } from "@tauri-apps/api/window";
import "./CommitGraph.css";

export interface CommitGraphProps {
    refCommitId: string;
}

const CommitGraph = (props: CommitGraphProps) => {
    const store = useGitStores();

    const graphRef = useRef<HTMLDivElement>(null);

    const openCommitDiff = async (row: CommitGraphInfo) => {
        const pos = await appWindow.innerPosition();
        new WebviewWindow(`commit:${row.hash}`, {
            url: `git_diff.html?path=${encodeURIComponent(store.repoInfo?.path ?? "")}&commitId=${row.hash}&summary=${encodeURIComponent(row.subject)}&commiter=${encodeURIComponent(row.committer.name)}`,
            title: `${store.repoInfo?.name ?? ""}(commit:${row.hash.substring(0, 8)})`,
            x: pos.x + Math.floor(Math.random() * 200),
            y: pos.y + Math.floor(Math.random() * 200),
        })
    };

    const initGraph = async () => {
        if (graphRef == null || graphRef.current == null) {
            return;
        }
        graphRef.current.innerText = "";
        const gitgraph = createGitgraph(graphRef.current, {
            responsive: true,
            template: {
                colors: ["#6963FF", "#47E8D4", "#6BDB52", "#E84BA5", "#FFA657"],
                branch: {
                    lineWidth: 2,
                    spacing: 20,
                    mergeStyle: MergeStyle.Straight,
                    label: {
                        display: true,
                        bgColor: "white",
                        borderRadius: 10,
                    },
                },
                commit: {
                    spacing: 40,
                    hasTooltipInCompactMode: false,
                    dot: {
                        size: 4,
                        font: "normal 14px monospace",
                    },
                    message: {
                        color: "black",
                        display: true,
                        displayAuthor: false,
                        displayHash: true,
                        font: "normal 14px monospace",
                    },
                },
                arrow: {
                    color: null,
                    size: 8,
                    offset: -1.5,
                },
                tag: {},
            },
        });
        let commitList = await list_commit_graph(store.repoInfo?.path ?? "", props.refCommitId);
        if (commitList.length > 200) {
            commitList = commitList.slice(0, 199);
        }
        for (const commit of commitList) {
            const options = commit as any as CommitOptions;
            options.onClick = () => {
                openCommitDiff(commit);
            };
            options.onMessageClick = () => {
                openCommitDiff(commit);
            };
        }
        gitgraph.import(commitList);
    };

    useEffect(() => {
        if (graphRef != null && graphRef.current != null && store.repoInfo != null) {
            initGraph();
        }
    }, [graphRef, store.repoInfo, props.refCommitId]);

    return (
        <Layout>
            <Layout.Content style={{ height: "100vh", overflowY: "scroll" }}>
                <div ref={graphRef} />
            </Layout.Content>
        </Layout>
    );
}

export default observer(CommitGraph);